﻿using System.Collections.Generic;
using System.Linq;
using HHPS.CreditEducation.DataProvider;
using HHPS.CreditEducation.Frameworks.Constants;

namespace HHPS.CreditEducation.Business
{
    public class SubjectBusiness
    {
        private readonly CreditEducationDbEntities _dataContex;

        public SubjectBusiness()
        {
            _dataContex = new CreditEducationDbEntities();
        }

        #region -- Kind of Subject --

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public List<KindOfSubject> GetListKindOfSubject()
        {
            return _dataContex.KindOfSubjects.ToList();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="nameKindOfSubject"></param>
        /// <returns></returns>
        public string AddKindOfSubjectValidator(string nameKindOfSubject)
        {
            var impactednameKindOfSubjects = _dataContex.KindOfSubjects.Where(ks => ks.Name.ToLower() == nameKindOfSubject.ToLower());

            var listNames = Enumerable.Aggregate(impactednameKindOfSubjects, string.Empty, (current, kindofsubject) => current + (kindofsubject.Name + ","));

            return listNames.TrimEnd(',', ' ');
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="nameKindOfSubject"></param>
        public void AddNewKindOfSubjecty(string nameKindOfSubject)
        {
            _dataContex.KindOfSubjects.AddObject(new KindOfSubject { Name = nameKindOfSubject });

            _dataContex.SaveChanges();
        }

        public string EditKindOfSubjectValidator(int id, string nameKindOfSubject)
        {
            if (!_dataContex.KindOfSubjects.Any(ks => ks.Id == id))
                return ConstantMessages.CanNotIdentifyItem;

            var impactedKindOfSubjects = _dataContex.KindOfSubjects.Where(ks => ks.Name.ToLower() == nameKindOfSubject.ToLower() && ks.Id != id);

            var listNames = Enumerable.Aggregate(impactedKindOfSubjects, string.Empty, (current, kindofsubject) => current + (kindofsubject.Name + ","));

            return listNames.TrimEnd(',', ' ');
        }

        public void EditAKindOfSubject(int id, string nameKindOfSubject)
        {
            var kindofIdSubject = _dataContex.KindOfSubjects.Where(ks => ks.Id == id).FirstOrDefault();

            if (kindofIdSubject == null) return;

            kindofIdSubject.Name = nameKindOfSubject;

            _dataContex.SaveChanges();
        }

        public string DeleteKindOfSubjectValidator(int[] ids)
        {
            var deleteKindOfSubjects = _dataContex.KindOfSubjects.Where(ks => ids.Contains(ks.Id));

            // Can Not Identify Item
            if (_dataContex == null || deleteKindOfSubjects.ToList().Count != ids.Length)
                return string.Format(ConstantMessages.CanNotIdentifyItem);

            var subjectsForiegnKey = _dataContex.Subjects.Select(s => s.IdKindOfSubject);

            var impactedKindOfSubjects = deleteKindOfSubjects.Where(ks => subjectsForiegnKey.Contains(ks.Id)).ToList();

            var listNames = impactedKindOfSubjects.Aggregate(string.Empty, (current, kindofsubject) => current + (kindofsubject.Name + ", "));

            return listNames.TrimEnd(',', ' ');
        }

        public void DeleteSelectedKindOfSubject(int id)
        {
            var kindofsubject = _dataContex.KindOfSubjects.Where(ks => ks.Id == id).FirstOrDefault();

            _dataContex.DeleteObject(kindofsubject);

            _dataContex.SaveChanges();
        }
  
        #endregion

        #region -- Subject --

        /// <summary>
        /// 
        /// </summary>
        /// <param name="keyNameSubject"></param>
        /// <returns></returns>
        public List<Subject> GetListSubjectByKeyNameSubject(string keyNameSubject)
        {
            return string.IsNullOrEmpty(keyNameSubject) ? 
                _dataContex.Subjects.ToList() :
                _dataContex.Subjects.Where(s => s.Name.ToLower().Contains(keyNameSubject.ToLower())).ToList();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="idKindOfSubject"></param>
        /// <returns></returns>
        public List<Subject> GetListSubjectByKindOfSubject(int idKindOfSubject)
        {
            return idKindOfSubject > 0 ?
                _dataContex.Subjects.Where(s => s.IdKindOfSubject == idKindOfSubject).ToList() :
                _dataContex.Subjects.ToList();
        }

        public List<Subject> GetListSubject()
        {
            return _dataContex.Subjects.ToList();
        }

        public string AddSubjectValidator(string nameSubject, int numberOfCredit, int kindOfIdSubject)
        {
            if (_dataContex != null && numberOfCredit > 0  && _dataContex.KindOfSubjects.Any(ks => ks.Id == kindOfIdSubject))
            {
                var impactedSubjects = _dataContex.Subjects.Where(s => s.Name.ToLower() == nameSubject.ToLower());

                var listNames = Enumerable.Aggregate(impactedSubjects, string.Empty,
                                                     (current, subject) => current + (subject.Name + ","));

                return listNames.TrimEnd(',', ' ');
            }

            return string.Format(ConstantMessages.CanNotIdentifyItem);
        }

        public void AddNewSubject(string nameSubject, int numberOfCredit, int idKindOfSubject)
        {
            _dataContex.Subjects.AddObject(new Subject { Name = nameSubject,NumberOfCredit  = numberOfCredit, IdKindOfSubject = idKindOfSubject });

            _dataContex.SaveChanges();
        }

        public string EditSubjectValidator(int idSubject, string nameSubject, int numberOfCredit)
        {
            if (_dataContex == null || !_dataContex.Subjects.Any(s => s.Id == idSubject))
                return string.Format(ConstantMessages.CanNotIdentifyItem);

            var impactedSubjects = _dataContex.Subjects.Where(s => s.Name.ToLower() == nameSubject.ToLower() && s.Id != idSubject);

            var listNames = Enumerable.Aggregate(impactedSubjects, string.Empty, (current, subject) => current + (subject.Name + ","));

            return listNames.TrimEnd(',', ' ');
        }

        public void EditASubject(int id, string nameSubject, int numberOfCredit)
        {
            var idSubject = _dataContex.Subjects.Where(s => s.Id == id).FirstOrDefault();

            if (idSubject == null) return;

            idSubject.Name = nameSubject;

            idSubject.NumberOfCredit = numberOfCredit;

            _dataContex.SaveChanges();
        }

        public string DeleteSubjectValidator(int[] ids)
        {
            var deleteSubjects = _dataContex.Subjects.Where(s => ids.Contains(s.Id));

            if (_dataContex == null || deleteSubjects.ToList().Count != ids.Length)
                return string.Format(ConstantMessages.CanNotIdentifyItem);

            var subjectRequiredKey = _dataContex.SubjectRequires.Select(sq => sq.IdSubject);

            var impactedSubjects = deleteSubjects.Where(s => subjectRequiredKey.Contains(s.Id)).ToList();

            var listNames = impactedSubjects.Aggregate(string.Empty, (current, subject) => current + (subject.Name + ", "));

            return listNames.TrimEnd(',', ' ');
        }

        public void DeleteSelectedSubject(int id)
        {
            var subject = _dataContex.Subjects.Where(s => s.Id == id).FirstOrDefault();

            _dataContex.DeleteObject(subject);

            _dataContex.SaveChanges();
        }

        #endregion

        #region -- Subject Require --

        /// <summary>
        /// 
        /// </summary>
        /// <param name="idSubject"></param>
        /// <returns></returns>
        public List<SubjectRequire> GetListSubjectRequireBySubject(int idSubject)
        {
            return idSubject > 0 ?
                _dataContex.SubjectRequires.Where(sr => sr.IdSubject == idSubject).ToList() :
                _dataContex.SubjectRequires.ToList();
        }

        public string AddSubjectRequiredValidator(int idSubject, int idSubjectRequire)
        {
            if (_dataContex == null || !_dataContex.Subjects.Any(s => s.Id == idSubject) || !_dataContex.Subjects.Any(sr => sr.Id == idSubjectRequire))
                return string.Format(ConstantMessages.CanNotIdentifyItem);

            return _dataContex.SubjectRequires.Any(s => s.IdSubject == idSubject && s.IdSubjectRequire == idSubjectRequire) ? string.Format(ConstantMessages.ItemIsExisted, "điều kiện ràng buộc") : string.Empty;
        }

        public void AddNewSubjectRequire(int idSubject, int idSubjectRequire)
        {
            _dataContex.SubjectRequires.AddObject(new SubjectRequire { IdSubject = idSubject, IdSubjectRequire = idSubjectRequire });

            _dataContex.SaveChanges();
        }

        public string DeleteSubjectRequireValidator(int[] ids)
        {
            var deleteSubjectRequireds = _dataContex.SubjectRequires.Where(c => ids.Contains(c.Id));

            return deleteSubjectRequireds.ToList().Count != ids.Length ? ConstantMessages.CanNotIdentifyItem : string.Empty;
        }

        public void DeleteSubjectRequire(int id)
        {
            var subjectrequired = _dataContex.SubjectRequires.Where(sr => sr.Id == id).FirstOrDefault();

            _dataContex.DeleteObject(subjectrequired);

            _dataContex.SaveChanges();

        }

        #endregion
    }
}
